#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <stdio.h>

#include<iostream>
#include <gst/gst.h>
#include <stdio.h>

#include <sstream>
#include <string>

#include <stdlib.h>
#include <QDebug>
#include <dirent.h>
#include <QtCore/QTimer>
#include <QtCore/QTime>

using namespace std;

string audioPath;
QTimer timePosition;

/*Main object*/
GMainLoop *loop;

/*Elements*/
GstElement *source,
            *mad,
            *pipeline,
            *convert,
            *rtp, /* RTP packer */
            *udp, /* UDP sender */
            *volume;

float volumen = 1.0;

void MainWindow::updateSlider(bool playing)
{
    if(playing){
        timePosition.start(700);
    } else {
        timePosition.stop();
    }
}

/* This method executes to send the mp3 file song to a determine IP
 * and port to be listened*/
void sendMp3Audio ()
{

    char *audioFileName = (char*)malloc(1024*sizeof(char));

    strcpy(audioFileName, audioPath.c_str());

    loop = g_main_loop_new (NULL, FALSE);


    /* Create gstreamer elements */
    pipeline = gst_pipeline_new ("mp3 player");
    source = gst_element_factory_make ("filesrc", "filesrc");

    /* we set the input filename to the source element */
    g_object_set (G_OBJECT (source), "location", audioFileName , NULL);

    mad = gst_element_factory_make ("mad", "mad");


    volume   =  gst_element_factory_make ("volume","volume");

    g_object_set (G_OBJECT (volume), "volume", volumen, NULL);

    convert = gst_element_factory_make("audioconvert", NULL);

    rtp = gst_element_factory_make("rtpL16pay", "rtpL16pay");
    udp = gst_element_factory_make("udpsink", "udpsink");

    g_object_set( udp, "host", "192.168.1.118", "port", 5000, NULL );

    if (!pipeline || !source || !mad || !convert || !rtp || !udp) {
            g_printerr ("One element could not be created. Exiting.\n");
            //return -1;
        }

    /* we add all elements into the pipeline */
    gst_bin_add_many(GST_BIN(pipeline), source, mad, convert, rtp, udp, NULL);

    /* we link the elements together */
    gst_element_link_many (source, mad, convert, rtp, udp, NULL);

    /* Set the pipeline to "playing" state*/
    g_print ("Now playing: %s\n", audioFileName);
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    /* Iterate */
    g_print ("Running...\n");
    g_main_loop_run (loop);

    /* Stop playback */
    g_print ("Stopping playback\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);

    /* Delete the pipeline */
    g_print ("Deleting pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));
    g_main_loop_unref (loop);

}

/* This method executes to play the mp3 file song in the BB_XM*/
void playMp3BB_xm()
{
    GstElement *output; /* audio output */

    char *audioFileName = (char*)malloc(1024*sizeof(char));

    strcpy(audioFileName, audioPath.c_str());

    loop = g_main_loop_new (NULL, FALSE);

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new ("mp3 player");
    source = gst_element_factory_make ("filesrc", "filesrc");

    /* we set the input filename to the source element */
    g_object_set (G_OBJECT (source), "location", audioFileName , NULL);

    mad = gst_element_factory_make ("mad", "mad");

    volume   =  gst_element_factory_make ("volume","volume");

    g_object_set (G_OBJECT (volume), "volume", volumen, NULL);

    output = gst_element_factory_make("alsasink", "alsasink");


    if (!pipeline || !source || !mad || !volume || !output) {
            g_printerr ("One element could not be created. Exiting.\n");
            //return -1;
        }

    /* we add all elements into the pipeline */
    gst_bin_add_many(GST_BIN(pipeline), source, mad,volume, output, NULL);

    /* we link the elements together */
    gst_element_link_many (source, mad,volume, output, NULL);

    /* Set the pipeline to "playing" state*/
    g_print ("Now playing: %s\n", audioFileName);
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

}

void stop_audio()
{
    gst_element_set_state (pipeline, GST_STATE_PAUSED);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    g_print ("Deleting pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));

}


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    QObject::connect(ui->spinBox,SIGNAL(valueChanged(int)),ui->dial,SLOT(setValue(int)));
    QObject::connect(ui->dial,SIGNAL(valueChanged(int)),ui->spinBox,SLOT(setValue(int)));
    QObject::connect(&timePosition, SIGNAL(timeout()), this, SLOT(updateTimer()));
    getMusicFileNames();

}

MainWindow::~MainWindow()
{
    delete ui;

}





/* This method executes when the Stop button is pressed*/
void MainWindow::on_buttonStop_clicked()
{
    stop_audio();

}

void MainWindow::getMusicFileNames()
{

    DIR *directory;
    struct dirent *files;
    if ((directory = opendir ("/home/papillo/Embebidos/Proyecto1/SendMp3/music/")) != NULL) {
   // if ((directory = opendir ("/media/sda1/")) != NULL) {
        /* print all the files and directories within directory */
        while ((files = readdir (directory)) != NULL) {

            QString musicFileName = files->d_name;
            if(musicFileName.contains(".mp3")) ComboList.append(musicFileName);
        }
        closedir (directory);
    }
    ui->comboBox->clear();
    ui->comboBox->addItems(ComboList);


}


/* This method executes when the Play button is pressed*/
void MainWindow::on_buttonPlay_clicked()
{
    //stop_audio();
    volumen = ui->spinBox->value()*0.01f;

    QString filePath = "/home/papillo/Embebidos/Proyecto1/SendMp3/music/";
   //QString filePath = "/media/sda1/";
    int index = ui->comboBox->currentIndex();
    filePath.append(ComboList.at(index));

    QByteArray byteArray = filePath.toUtf8();
    audioPath = byteArray.constData();
    cout <<"\nThe File Path is " << audioPath << endl; //Prints the file path


    if(ui->radioButtonClient->isChecked()){
        cout <<"\nSending audio to the Client" << endl;
        sendMp3Audio();
    }
    else if(ui->radioButtonBB->isChecked()){
        cout <<"\nSending audio to the Beagle Board XM" << endl;
        playMp3BB_xm();
    }

   updateSlider(true);
}

void MainWindow::on_dial_sliderMoved()
{
   volumen = ui->spinBox->value()*0.01f;
   g_object_set (G_OBJECT (volume), "volume", volumen, NULL);

}

void MainWindow::on_spinBox_valueChanged()
{
    volumen = ui->spinBox->value()*0.01f;
    g_object_set (G_OBJECT (volume), "volume", volumen, NULL);

}

void MainWindow::updateTimer()
{
    int position = 0;
    gint64 pos;
    GstFormat format = GST_FORMAT_TIME;
    if (gst_element_query_position (pipeline, &format, &pos)){
        position =  pos / GST_SECOND;
    }
    ui->horizontalSlider->setSliderPosition(position);
 }



